#include "qtsearchprocess.h"
#include <QProcess>
#include <QDebug>
#include <QSharedPointer>

static QString template_result = R"(/Users/choice/code/CopyQ/src/gui/tabtree.h:18-*/
/Users/choice/code/CopyQ/src/gui/tabtree.h:19-
/Users/choice/code/CopyQ/src/gui/tabtree.h:20:#ifndef TABTREE_H
/Users/choice/code/CopyQ/src/gui/tabtree.h:21:#define TABTREE_H
/Users/choice/code/CopyQ/src/gui/tabtree.h:22-
/Users/choice/code/CopyQ/src/gui/tabtree.h:23-#include "gui/tabswidgetinterface.h"
--
/Users/choice/code/CopyQ/src/gui/tabtree.h:114-};
/Users/choice/code/CopyQ/src/gui/tabtree.h:115-
/Users/choice/code/CopyQ/src/gui/tabtree.h:116:#endif // TABTREE_H
/Users/choice/code/CopyQ/src/gui/tabtree.h:117-)";

struct LineItem
{
    int lineNum;
    bool hasMatch;
    QString content;
    QString fileName;
};

class DataItem
{
public:
    DataItem(QVector<QString> lines)
    {
        for (QString line: lines)
        {
            LineItem item;
            auto indexOfColon = line.indexOf(":");
            fileName = line.left(indexOfColon);
            qDebug() << fileName;
            item.fileName = fileName;
            QString right = line.mid(indexOfColon + 1);
//            qDebug() << right;
            QString lineNumStr;
            int count = 0;
            for (auto c: right)
            {
                ++count;
                if (c.isDigit())
                {
                    lineNumStr.push_back(c);
                }
                else if(c == '-')
                {
                    item.hasMatch = false;
                    break;
                }
                else if (c == ':')
                {
                    item.hasMatch = true;
                    break;
                }
                else
                {
                    qWarning() << "output format is not supported";
                    break;
                }
            }
            item.lineNum = lineNumStr.toInt();
            item.content = right.mid(count);
            lineItems.push_back(item);
        }

    }
    QString fileName;
    QVector<LineItem> lineItems;
};



QtSearchProcess::QtSearchProcess(QObject *parent) : QObject(parent), m_result("")
{
    process = new QProcess(this);
    connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &QtSearchProcess::showResult);
    connect(process, &QProcess::readyReadStandardOutput, this, &QtSearchProcess::onReadResult);
    connect(process, &QProcess::readyReadStandardError, this, &QtSearchProcess::onReadError);
}

void QtSearchProcess::onSearchButton()
{
    qDebug() << "User clicked on the button!";
    m_result.clear();

    m_result = template_result;
    QVector<QSharedPointer<DataItem>> resultItems;
    auto resultLines = m_result.split("\n");

    QVector<QString> lines;
    for (int i = 0; i < resultLines.size(); i++)
    {
        auto line = resultLines[i];
        if (line.trimmed() == "--")
        {
            resultItems.push_back( QSharedPointer<DataItem>::create(lines));
            lines.clear();
        }
        else
        {
            lines.push_back(line);
        }
    }
    if (!lines.empty())
    {
        resultItems.push_back(QSharedPointer<DataItem>::create(lines));
    }
    qDebug() << resultItems.size();
    return;
//    if (process)
//    {
//        delete process;
//    }

//    QString agFile = "/Users/choice/code/the_silver_searcher/ag";
    QString agFile = "/usr/local/bin/ag";
    QStringList arguments;
    arguments.append("--parallel"); // 使用这个来使ag在QProcess执行方式下，输出filename
    arguments.append("-C");
//    arguments.append("--filename");
//    arguments.append("-H");
    arguments.append("BTREE");
    // must use absoulte dir below
    arguments.append("/Users/choice/code/CopyQ");
//    arguments.append(">temp.txt");
//    arguments.append("~/code/c");

//    QString exeFile = "/usr/local/opt/coreutils/libexec/gnubin/cat";
//    QStringList arguments;
//    arguments.append("/Users/choice/test_qt.txt");

//    process->setStandardOutputFile("/Users/choice/test_cat.txt");

    process->start(agFile, arguments);
}

void QtSearchProcess::showResult(int exitCode, QProcess::ExitStatus exitStatus)
{
    qDebug() << exitCode << " " << exitStatus;
    qDebug() << "process finished!";
    process->close();

    qDebug().noquote() << m_result;

    auto lines = m_result.split("");

    emit finished();
}

void QtSearchProcess::onReadResult()
{
    qDebug() << "process onReadResult!";
    auto output = process->readAllStandardOutput();
    auto result = QString::fromUtf8(output);
    m_result.append(result);
//    qDebug().noquote() << "Standard" << result;
}

void QtSearchProcess::onReadError()
{
    auto error = process->readAllStandardError();
    auto result = QString::fromUtf8(error);
    result = "Error: " + result;
    qDebug().noquote() << result;
}
